/*
 * funcionesDeConsola.c
 *
 *  Created on: 20/10/2011
 *      Author: utn_so
 */

#include "funcionesDeConsola.h"

extern uint16_t posActualCabezal;
extern t_sector *sectorSacado;
extern sem_t sem_trace;
extern sem_t fin_trace;
extern sem_t sem_cola;
extern sem_t sem_sacar;
extern tipoConfigPPD configuracion;

void info(int8_t socket, char *buffer) {
	t_direccion_fisica pos_actual;
	pos_actual = obtener_dir_fis(posActualCabezal);
	sprintf(buffer, "La posicion actual del cabezal es %d:%d\n", pos_actual.cilindro,pos_actual.sector);
	if (send(socket, buffer, strlen(buffer), 0) == -1) {
		perror("send");
		exit(1);
	}
	sprintf(buffer, "----------------- Fin Info ----------------- \n");
	if (send(socket, buffer, strlen(buffer), 0) == -1) {
		perror("send");
		exit(1);
	}
}

void clean(int8_t socket, char* buffer, uint16_t posInicial, uint16_t posFinal, cola var_cola
		, cola v_cola_inact) {
	uint16_t posActual;
	t_sector *sector;
	sector = (t_sector*) malloc(sizeof(t_sector));
	char *blancos;
	blancos = (char*) malloc(512);
	memset(blancos, '\0', 512);
	sector->type = 2;
	memcpy(sector->datos, blancos,512);
	sem_wait(&sem_cola);
	for (posActual = posInicial; posActual <= posFinal; posActual++) {
		sector->numero = posActual;
		if(strcmp(configuracion.algoritmo,"SSTF") == 0) PONER_EN_COLA_SSTF(*sector,var_cola);
		//if(strcmp(configuracion.algoritmo,"FSCAN") == 0) PONER_EN_COLA_FSCAN(*sector,var_cola,v_cola_inact);
	}
	sem_post(&sem_sacar);
	sem_post(&sem_cola);
	sprintf(buffer, "----------------- Fin Clean ----------------- \n");
	if (send(socket, buffer, strlen(buffer), 0) == -1) {
		perror("send");
		exit(1);
	}
}

void trace(int8_t socket, char* buffer, int16_t *parametros, cola var_cola, cola v_cola_inact) {
	t_sector *sector;
	sector = (t_sector*)malloc(sizeof(t_sector));
	sector->type = 3;
	uint16_t i = 0, tiempoTotal = 0, recorrer_trace;
	int16_t nroSectorSacado = -1;
	t_direccion_fisica dir_fis_sect_solicitado, dir_fis_sect_actual,
			dir_fisica_proximo,dir_fisica_trace,actual;
	sem_wait(&sem_cola);
	while (parametros[i] != -1 && i < 5) {
		sector->numero = parametros[i];
		if(strcmp(configuracion.algoritmo,"SSTF")== 0) PONER_EN_COLA_SSTF(*sector,var_cola);
		//if(strcmp(configuracion.algoritmo,"FSCAN")== 0) PONER_EN_COLA_FSCAN(*sector,var_cola,v_cola_inact);
		i++;
	}
	i--;
	sem_post(&sem_sacar);
	sem_post(&sem_cola);
	while (nroSectorSacado != parametros[i]) {
		sem_wait(&sem_trace);
		nroSectorSacado = sectorSacado->numero;
		sem_post(&fin_trace);
		dir_fis_sect_actual = obtener_dir_fis(posActualCabezal);
		sprintf(buffer, "Posicion actual: %d:%d \n",
				dir_fis_sect_actual.cilindro, dir_fis_sect_actual.sector);
		if (send(socket, buffer, strlen(buffer), 0) == -1) {
			perror("send");
			exit(1);
		} // Esto envia por socket la posicion actual
		dir_fis_sect_solicitado = obtener_dir_fis(nroSectorSacado);
		sprintf(buffer, "Sector solicitado: %d:%d \n",
				dir_fis_sect_solicitado.cilindro,
				dir_fis_sect_solicitado.sector);
		if (send(socket, buffer, strlen(buffer), 0) == -1) {
			perror("send");
			exit(1);
		}
		sprintf(buffer, "Sectores recorridos: ");
		recorrer_trace = posActualCabezal;
		dir_fisica_trace = obtener_dir_fis(recorrer_trace);
		if (dir_fisica_trace.sector < dir_fis_sect_solicitado.sector) {

			while (dir_fisica_trace.sector < dir_fis_sect_solicitado.sector) {

				actual = obtener_dir_fis(recorrer_trace + 1);
				sprintf(buffer, "%s %d:%d, ", buffer, actual.cilindro,
						actual.sector);
				recorrer_trace++;
				dir_fisica_trace = obtener_dir_fis(recorrer_trace);
			}
			recorrer_trace--;
		}
		/*if (recorrer_trace > *sectorSacado) {
			t_direccion_fisica actual;
			while (recorrer_trace > *sectorSacado) {
				actual = obtener_dir_fis(recorrer_trace - 1);
				sprintf(buffer, "%s %d:%d, ", buffer, actual.cilindro,
						actual.sector);
				recorrer_trace--;
			}
			recorrer_trace++;
		}*/
		sprintf(buffer, "%s \n", buffer);
		if (send(socket, buffer, strlen(buffer), 0) == -1) {
			perror("send");
			exit(1);
		}
		tiempoTotal = tiempo_pista(posActualCabezal, nroSectorSacado);
		sprintf(buffer, "Tiempo consumido: %dms\n", tiempoTotal);
		if (send(socket, buffer, strlen(buffer), 0) == -1) {
			perror("send");
			exit(1);
		}
		posActualCabezal = nroSectorSacado;
		posActualCabezal++;
		if ((*var_cola) != NULL) {
			dir_fisica_proximo = obtener_dir_fis((*var_cola)->elemento.numero);
			sprintf(buffer, "Proximo sector: %d:%d \n\n",
					dir_fisica_proximo.cilindro, dir_fisica_proximo.sector);
			if (send(socket, buffer, strlen(buffer), 0) == -1) {
				perror("send");
				exit(1);
			}
		} else {
			sprintf(buffer, "----------------- Fin Trace ----------------- \n");
			if (send(socket, buffer, strlen(buffer), 0) == -1) {
				perror("send");
				exit(1);

			}
		}
	}
}

void ver_cola(int8_t socket,cola v_cola, char *buffer){
	cola actual;
	actual = v_cola;
	char tipo[9];
	while(actual != NULL){
	sprintf(buffer, "Sector: %d \n",
					(*actual)->elemento.numero);
			if (send(socket, buffer, strlen(buffer), 0) == -1) {
				perror("send");
				exit(1);
			}
	switch((*actual)->elemento.type){
	case(1):
			strcpy(tipo, "leer");
			break;
	case(2):
			strcpy(tipo, "escribir");
				break;
	case(3):
			strcpy(tipo,"trace");
				break;
	default:
			strcpy(tipo, "No se");
					break;
	}

	sprintf(buffer, "Tipo: %s \n\n",
								tipo);
						if (send(socket, buffer, strlen(buffer), 0) == -1) {
							perror("send");
							exit(1);
						}
	sprintf(buffer, "----------------- Fin Trace ----------------- \n");
						if (send(socket, buffer, strlen(buffer), 0) == -1) {
							perror("send");
							exit(1);

						}
	(*actual) = (*actual)->siguiente;
	}
}

void interpretar(int8_t socket, char* buffer, char* funcion, cola var_cola, cola v_cola_inact) {

	char *nombreFuncion, *siguienteToken, *actual;
	int16_t parametros[5] = { -1, -1, -1, -1, -1 }, i = 0;

	nombreFuncion = strtok_r(funcion, " ", &siguienteToken);

	switch (nombreFuncion[0]) {
	case ('i'):
		info(socket, buffer);
		break;

	case ('c'):
		parametros[0] = atoi(strtok_r(siguienteToken, " ", &siguienteToken));
		parametros[1] = atoi(strtok_r(siguienteToken, " ", &siguienteToken));
		clean(socket, buffer, parametros[0], parametros[1], var_cola, v_cola_inact);
		break;
	case ('t'):
		while (nombreFuncion != NULL) {
			actual = siguienteToken;
			nombreFuncion = strtok_r(actual, " ", &siguienteToken);
			if (nombreFuncion != NULL)
			{
				parametros[i] = atoi(nombreFuncion);
			};
			i++;
		}
		;
		trace(socket, buffer, parametros, var_cola, v_cola_inact);
		break;
	case ('v'):
		ver_cola(socket, var_cola, buffer);
			break;
	default:
		sprintf(buffer, "La funcion %s no es soportada \n", nombreFuncion);
		if (send(socket, buffer, strlen(buffer), 0) == -1) {
			perror("send");
			exit(1);
		}
		break;
	}
}
